home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Codecs / DrawTextCodec / CodecTestMain.c next >
Encoding:
C/C++ Source or Header  |  1992-10-19  |  24.9 KB  |  1,157 lines  |  [TEXT/KAHL]

  1. /*
  2.  
  3.     Written by:    Mark Krueger
  4.  
  5.     Copyright:    © 1992 by Apple Computer, Inc., all rights reserved.
  6.  
  7. */
  8.  
  9.  
  10. #ifdef    THINK_C
  11. //#define    OpenStdCompression    OPENSTDCOMPRESSION
  12. #endif
  13.  
  14.  
  15. #include    <QuickTimeComponents.h>
  16. #include    <ImageCompression.h>
  17. #include    "DrawTextCodec.h"
  18.  
  19. #define    dangerousPattern
  20.  
  21. //#define    DONT_SHOW_PICTURE
  22. //#define    DONT_DO_PREVIEW
  23.  
  24. #include    <Types.h>
  25. #include    <Files.h>
  26. #include    <Quickdraw.h>
  27. #include    <Packages.h>
  28. #include    <Memory.h>
  29. #include    <Fonts.h>
  30. #include    <Events.h>
  31. #include    <OSUtils.h>
  32. #include    <ToolUtils.h>
  33. #include    <Menus.h>
  34. #include    <Dialogs.h>
  35. #include    <stdio.h>
  36. #include    <Errors.h>
  37. #include    <Scrap.h>
  38. #include    <Desk.h>
  39. #include    <string.h>
  40. #include    <GestaltEqu.h>
  41. #include    <Resources.h>
  42. #include    <Finder.h>
  43. #include    <PictUtil.h>
  44. #include    <palettes.h>
  45. #include    <PictUtil.h>
  46. #include    <QDOffscreen.h>
  47. #include    <Windows.h>
  48.  
  49. #ifndef    THINK_C
  50. #include    <Strings.h>
  51. #endif
  52.  
  53.  
  54. #include    "ImageCompression.h"
  55.  
  56.  
  57.  
  58. #define        appleMenuID        128
  59. #define        fileMenuID        129
  60. #define        editMenuID        130
  61.  
  62.  
  63. #define        M_OPEN            1
  64. #define        M_CLOSE            3
  65. #define        M_SAVE            4
  66. #define        M_COMP            6
  67. #define        M_QUIT            8
  68.  
  69. #define        M_COPY            4
  70. #define        M_PASTE            5
  71. #define        M_FIT            10
  72.  
  73.  
  74. Boolean        gDitherFlag  = false;
  75. StandardFileReply    gOriginalSFR;    
  76. short            gOriginalFile;
  77. Cursor            **gWatch;
  78. short            gCompressedFile;
  79. Boolean            gExitFlag = false;
  80. MenuHandle        gMenus[3];            // our menus
  81. CWindowPtr        gActiveWindow = nil;
  82. CWindowPtr        gOrigWindow = nil;
  83. CWindowPtr        gCompWindow = nil;
  84. Rect            gOriginalPicFrame;
  85. Rect            gZoomedPictureFrame;
  86. Boolean            gZoomed = false;
  87. Boolean            gFitToWindow = true;
  88. Boolean            gHasNewStdFile = false;
  89. PicHandle        gOriginalPicture = nil;
  90. Boolean            gCompressed = false;
  91. Boolean            gSevenOh = false;
  92. short            gDepth = 1;
  93.  
  94.  
  95. ComponentInstance    gSCComponent;
  96. SCParams            gSCParams;
  97.  
  98. Boolean            gDidError = false;
  99.  
  100. GWorldPtr    gworld,compgworld;
  101.  
  102. /************************************************
  103.  *
  104.  *    Set up application environment.
  105.  *
  106.  ************************************************/
  107.  
  108.  
  109. Initialize()
  110. {
  111.     Ptr    size;
  112.     
  113.     size = GetApplLimit();
  114.     SetApplLimit(size - 32*1024);        /* make room on stack so Quickdraw can do big pictures */
  115.     MaxApplZone();
  116.  
  117.     /*    initialize managers */
  118.  
  119.     InitGraf(&qd.thePort);
  120.     InitFonts();
  121.     InitWindows();
  122.     InitMenus();
  123.     InitDialogs(nil);
  124.     InitCursor();
  125.     ErrorSound(nil);
  126.     
  127.     /*    install menus */
  128.     
  129.     if ( (gMenus[0] = GetMenu(appleMenuID)) == nil )
  130.         return(-1);
  131.     AddResMenu(gMenus[0], (ResType) 'DRVR');
  132.     InsertMenu(gMenus[0], 0);
  133.     if ( (gMenus[1] = GetMenu(fileMenuID)) == nil )
  134.         return(-1);
  135.     InsertMenu(gMenus[1], 0);
  136.     if ( (gMenus[2] = GetMenu(editMenuID)) == nil )
  137.         return(-1);
  138.     InsertMenu(gMenus[2], 0);
  139.     DrawMenuBar();
  140.     if ( (gWatch =  GetCursor(watchCursor)) == nil )
  141.         return(-1);
  142.     HNoPurge((Handle)gWatch);
  143.     return(0);
  144. }
  145.  
  146.  
  147. /************************************************
  148.  *
  149.  *    Report errors as needed.
  150.  *
  151.  ************************************************/
  152.  
  153. Error(char *msg)
  154. {
  155.     SysBeep(1);
  156.     ParamText("\pError:",c2pstr(msg),nil,nil);    /* oops da baby */
  157.     Alert(128,nil);
  158. }
  159.  
  160.  
  161. /************************************************
  162.  *
  163.  *    Progress proc called from the Image Compression manager.
  164.  *
  165.  ************************************************/
  166.  
  167.  
  168. pascal OSErr
  169. Progress(short progressMsg,Fixed progressPercent,long refcon)
  170. {
  171.     OSErr  result = noErr;
  172.     short kind;
  173.     Handle h;
  174.     Rect r;
  175.     CGrafPtr savePort,wmgPort;
  176.     GDHandle saveGD;
  177.     static DialogPtr progressDialog = 0;
  178.     KeyMap    keys;
  179.  
  180.     switch (progressMsg) {
  181.     
  182.     case codecProgressOpen:
  183.     
  184.         progressDialog = 0;
  185.         GetGWorld(&savePort,&saveGD);
  186.         GetCWMgrPort(&wmgPort);
  187.         SetGWorld(wmgPort,nil);
  188.         if ( refcon != -1 && (progressDialog = GetNewDialog(5002, 0, (WindowPtr)-1)) != nil ) { 
  189.             ShowWindow((WindowPtr)progressDialog);
  190.             SetGWorld((CGrafPtr)progressDialog,nil);
  191.             DrawDialog(progressDialog);
  192.             GetDItem(progressDialog, 1, &kind, &h, &r);
  193.             InsetRect(&r, -1, -1);
  194.             FrameRect(&r);
  195.             InsetRect(&r, 1, 1);
  196.         }
  197.         SetGWorld(savePort,saveGD);
  198.         break;
  199.  
  200.     case codecProgressUpdatePercent:
  201.     
  202.         if ( progressDialog ) {
  203.             GetGWorld(&savePort,&saveGD);
  204.             SetGWorld((CGrafPtr)progressDialog,nil);
  205.             GetDItem(progressDialog, 1, &kind, &h, &r);
  206.             
  207.             FillRect(&r,qd.gray);
  208.             r.right = r.left + FixRound( FixMul(progressPercent, FixRatio(r.right-r.left,1)));
  209.             PaintRect(&r);
  210.             SetGWorld(savePort,saveGD);
  211.         }    
  212.  
  213.         /* check for command period - not the best way, but it works */
  214.  
  215.         GetKeys(keys);
  216.         if ( (keys[1] & 0x8000) && ((0x800000 & keys[1]) || (0x2000000 & keys[1])  ) )
  217.             result = codecAbortErr;
  218.         break;
  219.     
  220.     case codecProgressClose:
  221.     
  222.         if ( progressDialog )
  223.             DisposDialog(progressDialog);
  224.         progressDialog = 0;
  225.         break;
  226.     }
  227.     return(result);
  228. }
  229.  
  230.     
  231. /************************************************
  232.  *
  233.  *    Allow the user to specify compression and an output file, and then
  234.  *  compress the picture and save the result in that file.
  235.  *
  236.  ************************************************/
  237.  
  238.  
  239. DoCompression(CWindowPtr    window)
  240. {
  241.     Str32        newName;
  242.  
  243.     /* StdFile stuff */
  244.     
  245.     CGrafPtr    savePort;
  246.     GDHandle    saveGD;
  247.  
  248.     /* for sepecifying compression */
  249.     
  250.     Rect        pictureFrame;
  251.     OSErr        result;
  252.     Boolean        inPlace;
  253.     Point        where;
  254.     ImageDescriptionHandle desc = nil;
  255.     Ptr    data = nil;
  256.     long    cdsize;
  257.     ProgressProcRecord    *progP,progressRec;
  258.     Str255        buf;
  259.     GrafPtr        wmPort;
  260.     
  261.     progressRec.progressProc = Progress;
  262.     progressRec.progressRefCon = 0;
  263.     progP = &progressRec;
  264.         
  265.  
  266.     if ( window == nil )
  267.         return;
  268.     pictureFrame = ((CGrafPtr)window)->portRect;
  269.  
  270.     /************************************************
  271.      *
  272.      *        Ask how the user wants to compress it.
  273.      *
  274.      ************************************************/
  275.  
  276.  
  277.     
  278.     SetCursor(&qd.arrow);
  279.     if (SCSetTestImagePixMap(gSCComponent,gworld->portPixMap,&gworld->portRect,0))
  280.         goto done;
  281.  
  282.  
  283.     GetWMgrPort(&wmPort);
  284.     SetPort(wmPort);
  285.     where.h = where.v = -2;        // position dialog on the best device
  286.     if (SCGetCompression(gSCComponent,&gSCParams,where))
  287.         goto done;
  288.     
  289.     /************************************************
  290.      *
  291.      *        Ask her for the name of the new file.
  292.      *
  293.      ************************************************/
  294.     
  295.  
  296.     SetCursor(*gWatch);
  297.  
  298.  
  299.     if ( (result=GetMaxCompressionSize(gworld->portPixMap,&gworld->portRect,
  300.             gSCParams.depth,gSCParams.spatialQuality,gSCParams.theCodecType,
  301.             gSCParams.theCodec,&cdsize)) != noErr ) {
  302.         Error("getting max comp size");
  303.         goto done;
  304.     }        
  305.     if ( (data=NewPtr(cdsize)) == nil ) {
  306.         Error("no mem for picture");
  307.         goto done;
  308.     }        
  309.     desc = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription));
  310.     if ( desc == nil ) {
  311.         DisposPtr(data);
  312.         Error("no mem for picture");
  313.         goto done;
  314.     }        
  315.         
  316.     if ( (result=FCompressImage(gworld->portPixMap,&gworld->portRect,
  317.                 gSCParams.depth,gSCParams.spatialQuality,gSCParams.theCodecType,
  318.                 gSCParams.theCodec,nil,0,0,nil,progP,
  319.                  desc,data)) != noErr   ) {
  320.          DisposPtr(data);
  321.          DisposHandle((Handle)desc);
  322.          if ( result != codecAbortErr ) 
  323.             Error("compressing picture");
  324.         goto done;
  325.     }    
  326.     
  327.     
  328.     NumToString((*desc)->dataSize,buf);
  329.     ParamText("\pCompressed to ",buf,"\pBytes",nil);
  330.     Alert(128,nil);
  331.     GetGWorld(&savePort,&saveGD);
  332.     SetGWorld(compgworld,nil);
  333.     
  334.     if ( (result=DecompressImage(data,desc,compgworld->portPixMap,
  335.                     &gworld->portRect,&compgworld->portRect,ditherCopy,nil)) != noErr ) {
  336.          DisposPtr(data);
  337.          DisposHandle((Handle)desc);
  338.         Error("compressing picture");
  339.         goto done;
  340.     }    
  341.      DisposPtr(data);
  342.      DisposHandle((Handle)desc);
  343.      SetGWorld(gCompWindow,nil);
  344.      InvalRect(&gCompWindow->portRect);
  345.     SetGWorld(savePort,saveGD);
  346. done:
  347.     gDidError = false;
  348.     SetCursor(&qd.arrow);
  349.     
  350.     return(result);
  351. }
  352.  
  353.     
  354.     
  355.     
  356.  
  357.  
  358. DoError()
  359. {
  360.     CGrafPtr    savePort;
  361.     GDHandle    saveGD;
  362.     short        i;
  363.     RGBColor    opColor;
  364.     
  365.     
  366.     GetGWorld(&savePort,&saveGD);
  367.     SetGWorld(compgworld,nil);
  368.     if ( !gDidError ) {
  369.         gDidError = true;
  370.         opColor.red = opColor.green = opColor.blue = 0;
  371.         OpColor(&opColor);
  372.         CopyBits((BitMap *)*gworld->portPixMap,(BitMap *)*((CGrafPtr)compgworld)->portPixMap,
  373.             &gworld->portRect,&compgworld->portRect,subPin,nil);
  374.     }
  375.     opColor.red = opColor.green = opColor.blue = 0xffff;
  376.     OpColor(&opColor);
  377.     CopyBits((BitMap *)*compgworld->portPixMap,(BitMap *)*((CGrafPtr)compgworld)->portPixMap,
  378.         &compgworld->portRect,&compgworld->portRect,addPin,nil);
  379.      SetGWorld(gCompWindow,nil);
  380.      InvalRect(&gCompWindow->portRect);
  381.     SetGWorld(savePort,saveGD);
  382. }
  383.  
  384.  
  385.     
  386. /************************************************
  387.  *
  388.  *    Massage a rectangle to fit on a device's screen.
  389.  *
  390.  ************************************************/
  391.  
  392.  
  393. FitRect(Rect *rect,short w,short h)
  394. {
  395.     short     n;
  396.     Rect    dRect;
  397.     GDHandle    gd;
  398.     
  399. //    dRect = *rect;
  400.     gd = GetGDevice();
  401.     dRect =(*gd)->gdRect;
  402.     dRect.top += 40;                                /* make way for title bar */
  403.     InsetRect(&dRect,16,16);
  404.  
  405.     if ( w < (dRect.right-dRect.left) &&  h < (dRect.bottom-dRect.top) ) {
  406.          dRect.right = dRect.left + w;
  407.          dRect.bottom = dRect.top + h;
  408.     } else if ( gFitToWindow ) {
  409.         n = dRect.top + ((dRect.right -dRect.left) * h)/w;
  410.         if ( n > dRect.bottom )
  411.             dRect.right = dRect.left +((dRect.bottom -dRect.top) * w)/h;
  412.         else 
  413.             dRect.bottom = n;
  414.     }
  415.     *rect = dRect;
  416.  
  417. }
  418.  
  419.  
  420.     
  421. /************************************************
  422.  *
  423.  *    Ask the user for a pict file to open and open it.
  424.  *
  425.  ************************************************/
  426.  
  427.  
  428. DoOpen(FSSpec *fsp)
  429. {
  430.     OpenCPicParams    originalPicHeader;
  431.     SFTypeList     types = { 'PICT',0 };
  432.     OSErr        result = noErr;
  433.     CTabHandle    clut;
  434.     long        size;
  435.     CGrafPtr    savePort;
  436.     GDHandle    saveGD;
  437.     Rect        rect;
  438.     
  439.     
  440.     if ( fsp == nil ) {
  441.         if ( gHasNewStdFile )
  442.             StandardGetFile(nil,1,types,&gOriginalSFR);
  443.         else {
  444.             SFReply        osfr;
  445.             Point    pt = {100,100};
  446.             
  447.             SFGetFile(pt,(ConstStr255Param)"",nil,1,types,nil,&osfr);
  448.             gOriginalSFR.sfGood = osfr.good;
  449.             gOriginalSFR.sfReplacing = osfr.copy;
  450.             gOriginalSFR.sfType = osfr.fType;
  451.             if ( osfr.good ) 
  452.                 FSMakeFSSpec(osfr.vRefNum,0L,osfr.fName,&gOriginalSFR.sfFile);
  453.         }
  454.         if ( !gOriginalSFR.sfGood  ) {
  455.             return(0);
  456.         }
  457.     } else {
  458.         gOriginalSFR.sfFile = *fsp;
  459.     }
  460.         
  461.     SetCursor(*gWatch);
  462.     if ((result=FSpOpenDF(&gOriginalSFR.sfFile,fsRdPerm,&gOriginalFile)) != noErr ) {
  463.         goto done;
  464.     }
  465.  
  466.     
  467.     
  468.     /************************************************
  469.      *
  470.      *    Get the picture frame, to see how big of a window to make.
  471.      *
  472.      ************************************************/
  473.  
  474.     if ( (result=GetPictureFileHeader(gOriginalFile,&gOriginalPicFrame,&originalPicHeader)) != noErr ) {
  475.         FSClose(gOriginalFile);
  476.         goto done;
  477.     }
  478.  
  479.  
  480.     /************************************************
  481.      *
  482.      *    Figure out the best screen to show the picture on, and if
  483.      *    it doesn't fit, then scale it to fit while maintaining aspect ratio.
  484.      *
  485.      ************************************************/
  486.     
  487.     
  488.     SetRect(&gZoomedPictureFrame,-32767,-32767,32767,32767);
  489.     FitRect(&gZoomedPictureFrame,gOriginalPicFrame.right-gOriginalPicFrame.left,
  490.         gOriginalPicFrame.bottom-gOriginalPicFrame.top);
  491.     gZoomed = false;
  492.  
  493.     /************************************************
  494.      *
  495.      *    Create a window for the picture, and set our port to it.
  496.      *
  497.      ************************************************/
  498.  
  499.     if ( (gOrigWindow = (CWindowPtr)NewCWindow(nil,&gZoomedPictureFrame,gOriginalSFR.sfFile.name,true,
  500.                 zoomDocProc,(WindowPtr)-1,true,0)) == nil ) {
  501.         FSClose(gOriginalFile);
  502.         result = -1;
  503.         goto done;
  504.     }
  505.     rect = gZoomedPictureFrame;
  506. //    OffsetRect(&rect,(rect.right-rect.left)+10,0);
  507.     OffsetRect(&rect,50,50);
  508.     if ( (gCompWindow = (CWindowPtr)NewCWindow(nil,&rect,"\pCompressed",true,
  509.                 zoomDocProc,(WindowPtr)-1,true,0)) == nil ) {
  510.         FSClose(gOriginalFile);
  511.         result = -1;
  512.         goto done;
  513.     }
  514.     SetPort((GrafPtr)gActiveWindow);
  515.     if ( GetEOF(gOriginalFile,&size) == noErr ) {
  516.         size -= 512;
  517.         if ( gOriginalPicture = (PicHandle)NewHandle(size) ) {
  518.             HLock((Handle)gOriginalPicture);
  519.             SetFPos(gOriginalFile,fsFromStart,512);
  520.             FSRead(gOriginalFile,&size,*(Handle)gOriginalPicture);
  521.             HUnlock((Handle)gOriginalPicture);
  522.             HPurge((Handle)gOriginalPicture);
  523.         }
  524.     }    
  525.     rect = gZoomedPictureFrame;    
  526.     OffsetRect(&rect,-rect.left,-rect.top);
  527.     
  528.     if ( (result=NewGWorld(&gworld,gDepth,&rect,nil,nil,0)) != 0 ) {
  529.         if ( (result=NewGWorld(&gworld,gDepth,&rect,nil,nil,8)) != 0 ) {
  530.             Error("No mem for gworld");
  531.             goto done;
  532.         }
  533.     }
  534.     if ( (result=NewGWorld(&compgworld,gDepth,&rect,nil,nil,0)) != 0 ) {
  535.         if ( (result=NewGWorld(&compgworld,gDepth,&rect,nil,nil,8)) != 0 ) {
  536.             Error("No mem for gworld");
  537.             DisposeGWorld(gworld);
  538.             gworld = nil;
  539.             goto done;
  540.         }
  541.     }
  542.     GetGWorld(&savePort,&saveGD);
  543.     SetGWorld(gworld,nil);
  544.     if ( gOriginalPicture && *gOriginalPicture) {
  545.         HNoPurge((Handle)gOriginalPicture);
  546.         if ( (result=DrawTrimmedPicture(gOriginalPicture,&rect,nil,gDitherFlag,nil)) != noErr  && result != codecAbortErr) {
  547.             SysBeep(1);
  548.         }
  549.         HPurge((Handle)gOriginalPicture);
  550.     }else {
  551.         if ( (result=DrawTrimmedPictureFile(gOriginalFile,&rect,nil,gDitherFlag,nil)) != noErr  && result != codecAbortErr) {
  552.             SysBeep(1);
  553.         }
  554.     }
  555.     
  556.     SetGWorld(compgworld,nil);
  557.     EraseRect(&compgworld->portRect);
  558.     SetGWorld(savePort,saveGD);
  559.     SetWRefCon((WindowPtr)gCompWindow,(long)compgworld);
  560.     SetWRefCon((WindowPtr)gOrigWindow,(long)gworld);
  561.     FSClose(gOriginalFile);
  562.     if ( gOriginalPicture ) {
  563.         DisposHandle((Handle)gOriginalPicture);
  564.         gOriginalPicture = nil;
  565.     }
  566. done:
  567.     SetCursor(&qd.arrow);
  568.     if ( result ) {
  569.         SysBeep(1);
  570.     }
  571.  
  572. }
  573.  
  574.     
  575. /************************************************
  576.  *
  577.  *    Close the window and the file and get rid of any temporary file we may have.
  578.  *
  579.  ************************************************/
  580.  
  581.  
  582. DoClose(CWindowPtr w)
  583. {
  584.     GWorldPtr    gw;
  585.     
  586.     if ( w == nil )
  587.         return;
  588.         
  589.     gw = (GWorldPtr)GetWRefCon((WindowPtr)w);
  590.     if ( gw ) {
  591.         DisposeGWorld(gw);
  592.     }
  593.     CloseWindow((WindowPtr)w);
  594.     if  ( w == gActiveWindow ) {
  595.         gActiveWindow = nil;
  596.     }
  597.     if ( w == gOrigWindow )    
  598.         gOrigWindow = nil;
  599.     if ( w == gCompWindow )    
  600.         gCompWindow = nil;
  601.     return(0);
  602. }
  603.  
  604. DoSave(CWindowPtr w) 
  605. {
  606.  
  607.     long    l,k;
  608.     OSErr    e = 0;
  609.     PicHandle    pict = nil;
  610.     long    i;
  611.     short    f = 0;
  612.     static Str255    name = "\pPICT";
  613.     StandardFileReply     sfr;
  614.     CGrafPtr    savePort;
  615.     GDHandle    saveGD;
  616.     GWorldPtr    gw;
  617.     long zero = 0;
  618.     
  619.         
  620.     gw = (GWorldPtr)GetWRefCon((WindowPtr)w);
  621.     if ( gw == nil )
  622.         return;
  623.     StandardPutFile((ConstStr255Param)"",name,&sfr);
  624.     if ( sfr.sfGood ) { 
  625.         GetGWorld(&savePort,&saveGD);
  626.         SetGWorld(gw,nil);
  627.         pict = OpenPicture(&gw->portRect);
  628.         ClipRect(&gw->portRect);
  629.         CopyBits((BitMap *)*gw->portPixMap,(BitMap *)*((CGrafPtr)gw)->portPixMap,
  630.             &gw->portRect,&gw->portRect,ditherCopy,nil);
  631.         ClosePicture();
  632.         SetGWorld(savePort,saveGD);
  633.         if ( (l=GetHandleSize((Handle)pict)) <= 10 ) {
  634.             DisposHandle((Handle)pict);
  635.             Error("Making Pict");
  636.             return;
  637.         }
  638.         FSpDelete(&sfr.sfFile);
  639.         if ( (e=FSpCreate(&sfr.sfFile,'ppxi','PICT',0)) != noErr  ) {
  640.             Error("Creating file");
  641.             return;
  642.         }
  643.         if ( (e=FSpOpenDF(&sfr.sfFile,fsRdWrPerm,&f)) != noErr ) {
  644.             Error("Opening file");
  645.             goto bail;
  646.         }
  647.         SetFPos(f,fsFromStart,0);
  648.         k = 4;
  649.         for ( i=0; i < 512/4; i++ ) {
  650.             if ( (e=FSWrite(f,&k,(char *)&zero)) != noErr ) {
  651.                 Error("Writing file");
  652.                 goto bail;
  653.             }
  654.         }
  655.         HLock((Handle)pict);
  656.         if ( (e=FSWrite(f,&l,(Ptr)*pict)) != noErr)  {
  657.             Error("Writing file");
  658.             goto bail;
  659.         }
  660.         SetEOF(f,l+512);
  661.  
  662. bail:    
  663.         if ( pict )    
  664.             DisposHandle((Handle)pict);
  665.         if ( f ) 
  666.             FSClose(f);
  667.         if ( e )
  668.             FSpDelete(&sfr.sfFile);
  669.         FlushVol(nil,sfr.sfFile.vRefNum);
  670.     }
  671. }
  672.  
  673.  
  674.  
  675.     
  676. /************************************************
  677.  *
  678.  *    Fix the menu hiliting based on conditions.
  679.  *
  680.  ************************************************/
  681.  
  682.  
  683. FixMenus()
  684. {
  685.     long    offset;
  686.     
  687.     if ( gActiveWindow == nil ) {
  688.         EnableItem(gMenus[1],M_OPEN);
  689.         DisableItem(gMenus[1],M_CLOSE);
  690.         DisableItem(gMenus[1],M_SAVE);
  691.         DisableItem(gMenus[2],M_COPY);
  692.     } else  { 
  693.         DisableItem(gMenus[1],M_OPEN);
  694.         EnableItem(gMenus[1],M_CLOSE);
  695.         EnableItem(gMenus[1],M_SAVE);
  696. //        EnableItem(gMenus[2],M_COPY);
  697.     }
  698.     
  699.     if ( gOrigWindow != nil && gCompWindow != nil ) 
  700.         EnableItem(gMenus[1],M_COMP);
  701.     else
  702.         DisableItem(gMenus[1],M_COMP);
  703.     EnableItem(gMenus[2],M_FIT);
  704. //    if ( GetScrap(nil,'PICT',&offset) > 0  ) 
  705. //        EnableItem(gMenus[2],M_PASTE);
  706. //    else
  707.         DisableItem(gMenus[2],M_PASTE);
  708. }
  709.  
  710.     
  711. /************************************************
  712.  *
  713.  *    Paste the PICT from the clip board into a new window, making a temporary
  714.  *  file for it.
  715.  *
  716.  ************************************************/
  717.  
  718.  
  719. DoPaste()
  720. {
  721. }
  722.  
  723.     
  724. /************************************************
  725.  *
  726.  *    Copy the open PICT onto the clip board.
  727.  *
  728.  ************************************************/
  729.  
  730.  
  731. DoCopy(CWindowPtr w)
  732. {
  733.  
  734. }
  735.     
  736.  
  737. /************************************************
  738.  *
  739.  *    Update the window from the PICT file.
  740.  *
  741.  ************************************************/
  742.  
  743. DoUpdate(CWindowPtr w)
  744. {
  745.     CGrafPtr        savePort;
  746.     GDHandle        saveGD;
  747.     Rect        srcRect;
  748.     OSErr        result;
  749.     GWorldPtr    gw;
  750.  
  751.  
  752.     if ( w == nil ) 
  753.         return;
  754.     SetCursor(*gWatch);
  755.     GetGWorld(&savePort,&saveGD);
  756.     SetGWorld((CGrafPtr)w,nil);
  757.     
  758.     gw = (GWorldPtr)GetWRefCon((WindowPtr)w);
  759.     if ( gw  ) { 
  760.         srcRect = gw->portRect;
  761.         BeginUpdate((WindowPtr)w);
  762.         CopyBits((BitMap *)*gw->portPixMap,(BitMap *)*((CGrafPtr)w)->portPixMap,
  763.             &srcRect,&((CGrafPtr)w)->portRect,ditherCopy,nil);
  764.     
  765.         EndUpdate((WindowPtr)w);
  766.     }
  767.     SetGWorld(savePort,saveGD);
  768.     SetCursor(&qd.arrow);
  769.  
  770. }
  771.  
  772.     
  773. /************************************************
  774.  *
  775.  *    Resize the window and remember the old size, and force it to update.
  776.  *
  777.  ************************************************/
  778.  
  779.  
  780. DoSizeWindow(CWindowPtr wind,short h,short v,Boolean fup)
  781. {
  782.     GrafPtr    savePort;
  783.  
  784.     gZoomed = false;
  785.     GetPort(&savePort);
  786.     SetPort((GrafPtr)wind);
  787.     SizeWindow((WindowPtr)wind,h,v,false);
  788.     gZoomedPictureFrame = ((CGrafPtr)wind)->portRect;
  789.     LocalToGlobal((Point *)&gZoomedPictureFrame.top);
  790.     LocalToGlobal((Point *)&gZoomedPictureFrame.bottom);
  791.     if ( fup )
  792.         InvalRect(&((CWindowPtr)wind)->portRect);
  793.     SetPort(savePort);
  794. }
  795.  
  796.     
  797. /************************************************
  798.  *
  799.  *    Handle clicks in the window zoom box.
  800.  *
  801.  ************************************************/
  802.  
  803. DoZoom(WindowPtr wind)
  804. {
  805.     Rect         rect;
  806.     Rect         saveRect;
  807.     GrafPtr        savePort;
  808.     KeyMap        keys;
  809.     Boolean        doOriginal;
  810.     
  811.     GetPort(&savePort);
  812.     SetPort((GrafPtr)wind);
  813.  
  814.     GetKeys(keys);
  815.     doOriginal = (( keys[1] & 4 ) != 0);        /* option key */
  816.  
  817.     if ( doOriginal ) {
  818.         gZoomed = false;
  819.         FitRect(&gZoomedPictureFrame,gOriginalPicFrame.right-gOriginalPicFrame.left,
  820.             gOriginalPicFrame.bottom-gOriginalPicFrame.top);
  821.     } else {
  822.         if ( gZoomed ) {
  823.             gZoomed = false;
  824.         } else {
  825.             rect = gZoomedPictureFrame;
  826.             rect.top += 16;                        /* make way for title bar */
  827.             InsetRect(&rect,16,16);
  828.             ShowHide(wind,0);
  829.             MoveWindow(wind,rect.left,rect.top,true);
  830.             saveRect = gZoomedPictureFrame;
  831.             DoSizeWindow((CWindowPtr)wind,rect.right-rect.left,rect.bottom-rect.top,true);
  832.             gZoomedPictureFrame = saveRect;
  833.             gZoomed = true;
  834.             goto done;
  835.         }
  836.     }
  837.     ShowHide(wind,0);
  838.     MoveWindow(wind,gZoomedPictureFrame.left,gZoomedPictureFrame.top,true);
  839.     DoSizeWindow((CWindowPtr)wind,gZoomedPictureFrame.right-gZoomedPictureFrame.left,
  840.         gZoomedPictureFrame.bottom-gZoomedPictureFrame.top,true);
  841. done:
  842.     ShowHide(wind,1);
  843.     SetPort(savePort);
  844. }
  845.  
  846.  
  847.  
  848. /************************************************
  849.  *
  850.  *    Grow the window (constrain aspect ratio if option key pressed.
  851.  *
  852.  ************************************************/
  853.  
  854.  
  855. DoGrow(wind,where)
  856. WindowPtr wind;
  857. Point *where;
  858. {
  859.     unsigned long     size;
  860.     Rect            sizeRect;
  861.     GrafPtr            savePort;
  862.     short            h,v;
  863.     short            height = gOriginalPicFrame.bottom - gOriginalPicFrame.top;
  864.     short            width = gOriginalPicFrame.right - gOriginalPicFrame.left;
  865.     KeyMap            keys;
  866.     short            minH = 128,minV = 128,maxH = 4096,maxV = 4096;
  867.     Boolean            maintainAspect;
  868.     Rect            rect;
  869.     
  870.     
  871.     GetPort(&savePort);
  872.     SetPort((GrafPtr)wind);
  873.     GetKeys(keys);
  874.     maintainAspect = (( keys[1] & 4 ) != 0);
  875.     if ( maintainAspect ) {
  876.         Rect    oRect;
  877.         
  878.         rect = ((CGrafPtr)wind)->portRect;
  879.         LocalToGlobal((Point *)&rect.top);
  880.         LocalToGlobal((Point *)&rect.bottom);
  881.         oRect = rect;
  882.         if ( width > 2048 || height > 2048 )
  883.             FitRect(&rect,width,height);
  884.         else if ( width < 1024 && height < 1024 )
  885.             FitRect(&rect,width<<4,height<<4);
  886.         else
  887.             FitRect(&rect,width<<2,height<<2);
  888.         maxH = (rect.right - rect.left);
  889.         maxV = (rect.bottom - rect.top);
  890.         if ( maxV < minV || maxH < minH ) {
  891.             minV = maxV;
  892.             minH = maxH;
  893.         }
  894.         maxV = (maxH * height)/width;
  895.         minV = (minH * height)/width;
  896.     }
  897.     SetRect(&sizeRect,minH,minV,maxH,maxV);
  898.     if ( (size = GrowWindow(wind,*where,&sizeRect))  != 0 ) {
  899.         h = size & 0xffff;
  900.         v = size >> 16;
  901.         if ( maintainAspect )
  902.             v = (h * height)/width;
  903.         DoSizeWindow((CWindowPtr)wind,h,v,true);
  904.     }
  905.     SetPort(savePort);
  906.     FixMenus();
  907. }
  908.  
  909. /************************************************
  910.  *
  911.  *    Handle menu commands.
  912.  *
  913.  ************************************************/
  914.  
  915. DoCommand(long    mResult)
  916. {
  917.     short         theMenu, theItem;
  918.     GrafPtr    savePort;
  919.     Str255        daName;
  920.  
  921.     theItem = ((mResult) & 0xFFFF);
  922.     theMenu = (((mResult) >> 16) & 0xFFFF);        /* This is the resource ID */
  923.  
  924.     switch (theMenu) {
  925.     case appleMenuID:
  926.         if ( theItem != 1 ) {
  927.             GetItem(gMenus[0], theItem, daName);
  928.             GetPort(&savePort);
  929.             (void) OpenDeskAcc(daName);
  930.             SetPort(savePort);
  931.         }
  932.         break;
  933.  
  934.     case fileMenuID:
  935.         {
  936.             switch (theItem) {
  937.             case M_OPEN:
  938.                 DoOpen(nil);
  939.                 break;
  940.             case M_CLOSE:
  941.                 DoClose(gActiveWindow);
  942.                 break;
  943.             case M_COMP:
  944.                 DoCompression(gActiveWindow);
  945.                 break;
  946.             case M_SAVE:
  947.                 DoSave(gActiveWindow);
  948.                 break;
  949.             case M_QUIT:
  950.                 gExitFlag = true;            /* Request exit */
  951.                 break;
  952.             }
  953.             FixMenus();
  954.         }
  955.         break;
  956.     case editMenuID:
  957.         if ( !SystemEdit(theItem-1) ) {
  958.             switch ( theItem ) {
  959.             case M_COPY:
  960.                 DoCopy(gActiveWindow);
  961.                 break;
  962.             case M_PASTE:
  963.                 DoPaste();
  964.                 break;
  965.             case M_FIT:
  966.                 DoError();
  967.                 break;
  968.             default:
  969.                 break;
  970.             }
  971.         }
  972.         FixMenus();
  973.         break;
  974.     default:
  975.         break;
  976.     }
  977.     HiliteMenu(0);
  978. }
  979.  
  980. extern pascal ComponentResult DRAWTEXTCODEC(ComponentParameters *params,Handle storage);
  981.  
  982. /************************************************
  983.  *
  984.  *    Our program.
  985.  *
  986.  ************************************************/
  987.  
  988. main()
  989. {
  990.     GrafPtr    savePort;
  991.     EventRecord myEvent;
  992.     Rect        dragRect;
  993.     WindowPtr    whichWindow;
  994.     long        resp;
  995.  
  996.  
  997.     if ( Initialize() ) {
  998.         SysBeep(1);
  999.         ExitToShell();
  1000.     }
  1001.     
  1002.     if ( Gestalt(gestaltSystemVersion, &resp) != noErr || resp < 0x700 ) {
  1003.         gSevenOh = false;
  1004.     } else {
  1005.         gSevenOh = true;
  1006.     }
  1007.     
  1008.     /*    Check to make sure the image compression manager is installed. */
  1009.  
  1010.     if ( Gestalt(gestaltCompressionMgr, &resp) != noErr || resp < 15 ) {
  1011.         SysBeep(1);
  1012.         ExitToShell();
  1013.     }
  1014.  
  1015.     /*    Check to see if new style standard file is around. */
  1016.  
  1017.     gHasNewStdFile = ( Gestalt(gestaltStandardFileAttr,&resp) == 0 );
  1018.  
  1019.     /*    Install and open the standard compression component. */
  1020.  
  1021.     gSCComponent = OpenDefaultComponent('scdi',0);
  1022.     if (!gSCComponent) {
  1023.         SysBeep(1);
  1024.         ExitToShell();
  1025.     }
  1026.     
  1027.     /*    Set up the first defaults for compression dialog. */
  1028.     
  1029.     gSCParams.flags = scListEveryCodec;
  1030.     gSCParams.theCodecType = 'dtxt';
  1031.     gSCParams.theCodec = anyCodec;
  1032.     gSCParams.spatialQuality = codecNormalQuality;
  1033.     gSCParams.temporalQuality = 0;
  1034.     gSCParams.depth = 32;
  1035.  
  1036.  
  1037.  
  1038.     /* install CoDec to test */
  1039.  
  1040.  
  1041.  
  1042.      {
  1043.         ComponentDescription td;
  1044.     
  1045.         Handle    cname = NewHandle(sizeof(CODEC_NAME));
  1046.         Handle    dname = NewHandle(sizeof(CODEC_NAME));
  1047.     
  1048.         td.componentType = 'imco';
  1049.         td.componentSubType = 'dtxt';
  1050.         td.componentManufacturer = 'mark';
  1051.         td.componentFlags = codecInfoDoes1;
  1052.         td.componentFlagsMask = 0;
  1053.         
  1054.         
  1055.         BlockMove(CODEC_NAME,*cname,sizeof(CODEC_NAME));
  1056.         RegisterComponent(&td,DRAWTEXTCODEC, 0,cname,nil, nil);
  1057.             
  1058.         td.componentType = 'imdc';
  1059.         td.componentFlags = codecInfoDoes1;
  1060.         BlockMove(CODEC_NAME,*dname,sizeof(CODEC_NAME));
  1061.         RegisterComponent(&td,DRAWTEXTCODEC, 0,dname,nil, nil);
  1062.     }
  1063.  
  1064.  
  1065.     FixMenus();
  1066.     DoOpen(nil);
  1067.     
  1068.     while (!gExitFlag ) {
  1069.         
  1070.         if ( WaitNextEvent( everyEvent, &myEvent, 1, nil) == 0 )
  1071.             continue;
  1072.         
  1073.         switch (myEvent.what) {
  1074.         case mouseDown:
  1075.             switch ((short)FindWindow(myEvent.where, &whichWindow)) {
  1076.             case inSysWindow:
  1077.                 SystemClick(&myEvent, whichWindow);
  1078.                 FixMenus();
  1079.                 break;
  1080.  
  1081.             case inMenuBar:
  1082.                 DoCommand(MenuSelect(myEvent.where));
  1083.                 break;
  1084.  
  1085.             case inDrag:
  1086.                 GetPort(&savePort);
  1087.                 SetPort((GrafPtr)whichWindow);
  1088.                 SetRect(&dragRect, 4, 20 + 4, qd.screenBits.bounds.right-4, qd.screenBits.bounds.bottom-4);
  1089.                 DragWindow(whichWindow, myEvent.where, &dragRect);
  1090.                 gZoomedPictureFrame = ((CGrafPtr)whichWindow)->portRect;
  1091.                 LocalToGlobal((Point *)&gZoomedPictureFrame.top);
  1092.                 LocalToGlobal((Point *)&gZoomedPictureFrame.bottom);
  1093.                 SetPort(savePort);
  1094.                 break;
  1095.  
  1096.             case inGrow:
  1097.                 DoGrow(whichWindow,&myEvent.where);
  1098.                 break;
  1099.  
  1100.             case inGoAway:
  1101.                 if ( TrackGoAway(whichWindow,myEvent.where)  ) 
  1102.                     DoClose((CWindowPtr)whichWindow);
  1103.                 FixMenus();
  1104.                 break;
  1105.  
  1106.             case inZoomIn:
  1107.                 if ( TrackBox(whichWindow,myEvent.where,inZoomIn)  ) 
  1108.                     DoZoom(whichWindow);
  1109.                 break;
  1110.  
  1111.             case inZoomOut:
  1112.                 if ( TrackBox(whichWindow,myEvent.where,inZoomOut)  ) 
  1113.                     DoZoom(whichWindow);
  1114.                 break;
  1115.  
  1116.             case inContent:
  1117.                 if (whichWindow != FrontWindow()) 
  1118.                     SelectWindow(whichWindow);
  1119.                 break;
  1120.             
  1121.             default:
  1122.                 break;
  1123.             }
  1124.             break;
  1125.  
  1126.         case keyDown:
  1127.             if ( ((myEvent.modifiers & cmdKey) != 0) ) {
  1128.                 char key = myEvent.message & charCodeMask;
  1129.                 DoCommand(MenuKey(key));
  1130.             }
  1131.             break;
  1132.         
  1133.         case updateEvt :
  1134.  
  1135.             DoUpdate((CWindowPtr)myEvent.message);
  1136.             break;
  1137.         
  1138.         case activateEvt:
  1139.                 
  1140.             whichWindow=(WindowPtr)myEvent.message;
  1141.             if ( (myEvent.modifiers & activeFlag) == 0 ) 
  1142.                 gActiveWindow = nil;
  1143.              else 
  1144.                 gActiveWindow = (CWindowPtr)whichWindow;
  1145.             FixMenus();
  1146.             break;
  1147.     
  1148.         default:
  1149.             break;
  1150.             
  1151.         }
  1152.     }
  1153.     DoClose(gActiveWindow);
  1154.     CloseComponent(gSCComponent);
  1155.     ExitToShell();
  1156. }
  1157.